import React, { useEffect, useMemo, useRef, useState } from "react";

interface IParams {
  scrollY: number;
  rowHeight: number;
}

const defaultParams = {
  scrollY: 500,
  rowHeight: 48,
}

export default function VTrList({
  scrollY = defaultParams.scrollY,
  rowHeight = defaultParams.rowHeight,
}: Partial<IParams> = defaultParams) {

  const _params = { scrollY, rowHeight };
  return {
    body: {
      wrapper: createVWrapper(_params),
      row: createVRow(_params),
    }
  }
};

/**
 * 维护一个循环 key 数组，滚动时将最上面的一条 tr 挪到最下面。
 * @param params
 * @returns JSX.Element
 */
const createVWrapper = (params: IParams) => (props: any, refOrigin: any) => {
  const { scrollY, rowHeight } = params;
  const { children, ...restProps } = props;

  const refInner = useRef(null);
  const refTbody = refOrigin?.current ? refOrigin : refInner;
  const [scrollTop, setScrollTop] = useState(0);

  const offsetStart = scrollTop % rowHeight;
  const totalLen = children[1]?.length ?? 0;
  const renderLen = useMemo(() => Math.ceil(scrollY / rowHeight) + 1, []);
  const startIndex = Math.floor(scrollTop / rowHeight);
  const loopKeyArr = useMemo(() => Array(totalLen).fill(null).map((v, i) => i % renderLen), [totalLen, renderLen]);

  useEffect(() => {
    const handleScroll = (e) => {
      const curScrollTop = e.target?.scrollTop;
      setScrollTop(curScrollTop);
    };
    refTbody.current?.parentElement?.parentElement?.addEventListener('scroll', handleScroll);
    return () => {
      refTbody.current?.parentElement?.parentElement?.removeEventListener('scroll', handleScroll);
    }
  }, []);

  // 滑到最后可能会少一行
  const _startIndex = totalLen - startIndex < renderLen ? startIndex - 1 : startIndex;
  const computedChildren = useMemo(() => {
    return [
      children[0],
      children[1]?.slice(_startIndex, _startIndex + (renderLen || 1)).map((v, i) => ({ ...v, key: loopKeyArr[_startIndex + i] }))
    ]
  }, [children, _startIndex, renderLen, totalLen, loopKeyArr]);

  const totalHeight = totalLen * rowHeight;
  const scrolledRowHeight = scrollTop - offsetStart;
  const topHolderHeight = Math.min(scrolledRowHeight, totalHeight - renderLen * rowHeight);

  return (
    <tbody
      {...restProps}
      ref={refTbody}
      style={{
        ...restProps.style,
        height: totalHeight,
        transform: `translate3d(0, 0, 1px)`,
        zIndex: 4,
      }}
    >
      <tr
        key="topHolder"
        style={{
          height: topHolderHeight
        }}
      ></tr>
      {computedChildren}
      <tr
        key="bottomHolder"
        style={{
          height: (totalLen - renderLen) * rowHeight - topHolderHeight,
        }}
      ></tr>
    </tbody>
  )
}

const createVRow = (params: IParams) => (props: any) => {
  const { children, ...restProps } = props;
  console.log('ttttr=>>')
  return (
    <tr
      {...restProps}
    >
      {children}
    </tr>
  );
}
